/*
 * yDebugTools.cpp
 *
 *  Created on: Sep 17, 2016
 *      Author: root
 */

#include "yDebugTools.h"

void onCrashHandler(int signum) {
	FILE* f = fopen("log/crash.txt", "at");
	if (!f) {
		exit(1);
		return;
	}
	try {
		char szLine[512] = { 0, };
		time_t t = time(NULL);
		tm* now = localtime(&t);
		sprintf(szLine, "#########################################################\n[%04d-%02d-%02d %02d:%02d:%02d][crash signal number:%d]\n", now->tm_year + 1900, now->tm_mon + 1, now->tm_mday, now->tm_hour, now->tm_min, now->tm_sec, signum);
		fwrite(szLine, 1, strlen(szLine), f);
		void* array[MAX_STACK_FRAMES];
		size_t size = 0;
		char** strings = NULL;
		size_t i;
		signal(signum, SIG_DFL);
		size = backtrace(array, MAX_STACK_FRAMES);
		strings = (char**) backtrace_symbols(array, size);
		for (i = 0; i < size; ++i) {

			std::string symbol(strings[i]);
			std::string::size_type pos1 = symbol.find_first_of("[");
			std::string::size_type pos2 = symbol.find_last_of("]");
			std::string address = symbol.substr(pos1 + 1, pos2 - pos1 - 1);
			if (symbol.find("ydserver") != std::string::npos) {
				char cmd[128] = { 0, };
				sprintf(cmd, "addr2line -e $(pwd)/Debug/ydserver %s", address.c_str());
				FILE *pp = popen(cmd, "r");
				if (!pp) {
					exit(1);
					return;
				}
				char tmp[1024];
				if (fgets(tmp, sizeof(tmp), pp) != NULL) {
					char szLine[512] = { 0, };
					sprintf(szLine, "%d %s", i, tmp);
					fwrite(szLine, 1, strlen(szLine), f);
				}
			} else {
				char szLine[512] = { 0, };
				sprintf(szLine, "%d %s\n", i, strings[i]);
				fwrite(szLine, 1, strlen(szLine), f);
			}
			// fprintf(stderr, "%d %s\n",i, strings[i]);
		}
		free(strings);

	} catch (...) {
		//
	}
	fflush(f);
	fclose(f);
	f = NULL;
	exit(1);
}

void setCrashHook() {
	signal(SIGSEGV, onCrashHandler);
	signal(SIGABRT, onCrashHandler);
}
